package ext.tianma.bom.eco;

import java.lang.reflect.InvocationTargetException;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;

import wt.fc.ObjectReference;
import wt.fc.PersistenceHelper;
import wt.fc.collections.WTCollection;
import wt.log4j.LogR;
import wt.method.RemoteAccess;
import wt.method.RemoteMethodServer;
import wt.part.QuantityUnit;
import wt.part.SubstituteQuantity;
import wt.part.WTPart;
import wt.part.WTPartHelper;
import wt.part.WTPartMaster;
import wt.part.WTPartSubstituteLink;
import wt.part.WTPartUsageLink;
import wt.session.SessionServerHelper;
import wt.util.WTException;
import wt.vc.config.ConfigException;
import ext.com.core.CoreUtil;
import ext.tianma.bom.util.StringUtil;
import ext.tianma.part.MyPartUtil;
import ext.tianma.part.imported.ImportConstants;
import ext.tianma.part.imported.ImportedExcelUtil;

public class SubstituteLinkUtil implements RemoteAccess {
	private static final String CLASSNAME = SubstituteLinkUtil.class.getName() ;
	private static final Logger log = LogR.getLogger(SubstituteLinkUtil.class.getName());
	
	/**
	 * 检入已检出的零部件
	 * @param checkInPartList
	 */
	public static void checkInPartList(List<WTPart> checkInPartList) {
		
		if( checkInPartList == null || checkInPartList.size() == 0 ){
			return ;
		}
		
		Iterator< WTPart > checkInIterator = checkInPartList.iterator();
		while ( checkInIterator.hasNext() ) {
			WTPart part = checkInIterator.next();
			
			if( part != null ){
				try {
					CoreUtil.checkinObject(part, "导入替代料结构完成后，检入零部件。");
				} catch (WTException e) {
					e.printStackTrace();
				}
			}		
		}	
	}

	public static void importSubstituteLink(Row row,Map<Integer, String> header, StringBuffer subBuffer , List< WTPart >   checkInPartList,Set<String> errorPartList) {
		
		String parentNumber = "";
		String parentRersion = "";
		String parentView = "";
		String childNumber = "";
		//特定替代料编号
		String substituteNumber = "";
		String quantity = "";
		String unit = "";
		WTPart parentPart = null;
		WTPartMaster childPartMaster = null;
		WTPartMaster substituteMaster = null;
		
		try {
			Iterator<Cell> cellIterator = row.cellIterator();
			while (cellIterator.hasNext()) {
				Cell cell = cellIterator.next();
				if( cell != null ){
					int columnIndex =  cell.getColumnIndex();
					String head = header.get( columnIndex );
					if( head.equals( "Parent" ) ){
						parentNumber = ImportedExcelUtil.getCellValueAsString(cell,true).trim();
					}else if( head.equals( "Revision" ) ){
						parentRersion = ImportedExcelUtil.getCellValueAsString(cell,true).trim();
					}else if( head.equals( "View" ) ){
						parentView = ImportedExcelUtil.getCellValueAsString(cell).trim();
					}else if( head.equals( "Child" ) ){
						childNumber = ImportedExcelUtil.getCellValueAsString(cell,true).trim();
					}else if( head.equals( "Substitute" ) ){
						substituteNumber = ImportedExcelUtil.getCellValueAsString(cell,true).trim();
					}else if( head.equals( "Quantity" ) ){
						quantity = ImportedExcelUtil.getCellValueAsString(cell,true).trim();
					}else if( head.equals( "Unit of Measure" ) ){
						unit = ImportedExcelUtil.getCellValueAsString(cell).trim();
					}
				}						
			}
			
			parentPart = getParentPart(parentNumber, parentView, parentRersion);
			//根据编号获取childPartMaster
			childPartMaster = MyPartUtil.getWTPartMasterByNumber(childNumber);
			//根据编号获取替代料Master
			substituteMaster = MyPartUtil.getWTPartMasterByNumber(substituteNumber);
			if( parentPart != null && childPartMaster !=null && substituteMaster !=null){

				
				//检出父件
				parentPart =( WTPart ) CoreUtil.checkoutObject(parentPart);
				//添加到列表中
				if( !checkInPartList.contains( parentPart ) ){
					checkInPartList.add( parentPart );
				}
				//获取父件与子件的所有的关联关系
				List< WTPartUsageLink > usageLinkList = getWTPartUsageLink( parentPart , childPartMaster);
				log.info( "Debug   获取父件与子件所有的usageLink集合:"+ usageLinkList.size() );
				
				//构建单位数量对象（SubstituteQuantity）
				double sbustitueQuantity =  Double.parseDouble( quantity );
				QuantityUnit qu = null ;
				if( childPartMaster != null ){
					qu = childPartMaster.getDefaultUnit() ;
				}
				if( qu == null ){
					qu = QuantityUnit.toQuantityUnit( unit );
				}			
				SubstituteQuantity subQuantity = SubstituteQuantity.newSubstituteQuantity(sbustitueQuantity, qu);	
				
				ceateSubstituteLink( usageLinkList , substituteMaster ,subQuantity );
			}else{
				if(substituteMaster == null){
					errorPartList.add(substituteNumber);
				}
				log.info("ERROR 父件:" + parentNumber + "不存在,或者子件:" + childNumber + "不存在" + ",或者替代料:" + substituteNumber + "不存在");
				//throw new WTException("ERROR 父件:" + parentNumber + "不存在,或者子件:" + childNumber + "不存在" + ",或者替代料:" + substituteNumber + "不存在");
			}
		} catch (WTException e) {
			e.printStackTrace();
		}	
	}
	
	/**
	 * 创建特定替代关系(01)
	 * @param usageLinkList 父件与所有子件的UsageLink集合
	 * @param substituteMaster 特定替代料的Master
	 * @param quantity 数量单位对象
	 */
	private static void ceateSubstituteLink( List<WTPartUsageLink> usageLinkList , WTPartMaster substituteMaster ,SubstituteQuantity quantity) {
		if( usageLinkList == null || substituteMaster == null){
			return ;
		}
		
		Iterator< WTPartUsageLink > usageLinkListIte = usageLinkList.iterator();
		while ( usageLinkListIte.hasNext() ) {
			WTPartUsageLink usageLink = usageLinkListIte.next();
			
			if( usageLink != null ){
				ceateSubstituteLink(usageLink , substituteMaster ,quantity);
			}	
		}
	}
	
	/**
	 * 创建特定替代关系(02)
	 * @param usageLink
	 * @param substituteMaster
	 * @param quantity
	 */
	private static void ceateSubstituteLink(WTPartUsageLink usageLink,WTPartMaster substituteMaster ,SubstituteQuantity quantity) {
		if( usageLink != null && substituteMaster != null ){
			log.info( "Debug   substituteMaster"+substituteMaster.getNumber() + ",usageLink :父件," + usageLink.getUsedBy().getNumber() + ";子件," + usageLink.getUses().getNumber() );
			try {
				//返回的是一个特定替代关系集合
				WTCollection wtcol = WTPartHelper.service.getSubstituteLinks( usageLink ) ;
				log.info( "Debug   hasSubstituteLink( substituteMaster ,  wtcol):"+hasSubstituteLink( substituteMaster ,  wtcol) );
				if(!hasSubstituteLink( substituteMaster ,  wtcol)){
					createSubstituteLink(quantity, usageLink , substituteMaster );
				}			
			} catch (WTException e) {
				log.info( "Error ceateSubstituteLink, substituteMaster:"+substituteMaster.getNumber() + ",usageLink :父件," + usageLink.getUsedBy().getNumber() + ";子件," + usageLink.getUses().getNumber());
				e.printStackTrace();
			}
		}
	}

	/**
	 * 判断是否需要创建WTPartSubstituteLink （true为不用 false表示需要）
	 * @param substituteMaster
	 * @param wtcol
	 * @return
	 */
	private static boolean hasSubstituteLink(WTPartMaster substituteMaster, WTCollection wtcol) {
		boolean hasSubstituteLink = false;
		if( wtcol == null ){
			return hasSubstituteLink ; 
		}
		log.info( "Debug   wtcol："+wtcol.size() );
		Iterator wtcolIterator = wtcol.iterator();
		
		WTPartSubstituteLink wtSubstituteLink = null ;
		
		while( wtcolIterator.hasNext() ){
			Object object = wtcolIterator.next() ;
			
			if( object != null && object instanceof ObjectReference ){
				ObjectReference orf = ( ObjectReference )object;
				Object obj = orf.getObject();
				
				if( obj != null && obj instanceof WTPartSubstituteLink ){
					wtSubstituteLink = ( WTPartSubstituteLink )obj;
				}
			}else if( object != null && object instanceof WTPartSubstituteLink ){
				wtSubstituteLink = ( WTPartSubstituteLink ) object ;
			}
			
			if( wtSubstituteLink != null ){
				WTPartMaster subMaster = wtSubstituteLink.getSubstitutes();
				
				hasSubstituteLink = PersistenceHelper.isEquivalent(subMaster , substituteMaster ) ;
				if( hasSubstituteLink ){
					break;
				}
			}
		}
		
		return  hasSubstituteLink ;
	}
	
	/**
	 * 创建WTPartSubstituteLink对象
	 * @param quantity
	 * @param usageLink
	 * @param substituteMaster
	 */
	public static void createSubstituteLink(SubstituteQuantity quantity, WTPartUsageLink usageLink, WTPartMaster substituteMaster ) {
		if( usageLink == null || substituteMaster == null ){
			return;
		}
		log.info( "Debug   进入创建WTPartSubstituteLink方法..." );
		try {
			
			
			//创建WTPartSubstituteLink
			WTPartSubstituteLink wtSubstituteLink = WTPartSubstituteLink.newWTPartSubstituteLink(usageLink, substituteMaster);
			
			setQuantity( wtSubstituteLink , quantity );
			log.info( "Debug    开始保存WTPartSubstituteLink..." );
			wtSubstituteLink = (WTPartSubstituteLink) PersistenceHelper.manager.store( wtSubstituteLink );
			log.info( "Debug    保存WTPartSubstituteLink完毕..." );
		} catch (WTException e) {
			
			e.printStackTrace();
		}
		
	}
	
	/**
	 * 设置单位数量
	 * @param wtSubstituteLink
	 * @param quantity
	 */
	private static void setQuantity(WTPartSubstituteLink wtSubstituteLink, SubstituteQuantity quantity) {
		if( wtSubstituteLink == null ||  quantity == null || quantity.equals("") ){
			return ;
		}
		
		wtSubstituteLink.setQuantity(quantity);
	}
	
	/**
	 * 获取其父件与子件所有的usageLink关系
	 * @param parentPart
	 * @param childPartMaster
	 * @return
	 */
	public static List<WTPartUsageLink> getWTPartUsageLink(WTPart parentPart, WTPartMaster childPartMaster ) {
		List<WTPartUsageLink> usageLinkList = new ArrayList<WTPartUsageLink>();
		
		if( parentPart != null && childPartMaster != null ){
			try {
				List<WTPartUsageLink> allUsageLinkList = MyPartUtil.getFirstLevelUsageLink(parentPart);

				Iterator<WTPartUsageLink> allLinkIterator = allUsageLinkList.iterator();
				while( allLinkIterator.hasNext() ){
					WTPartUsageLink partUsageLink = allLinkIterator.next();
					WTPartMaster master =  partUsageLink.getUses();
					
					if( PersistenceHelper.isEquivalent(master, childPartMaster) ){
						usageLinkList.add(partUsageLink);
					}
				}
			} catch (ConfigException e) {
				e.printStackTrace();
			} catch (WTException e) {
				e.printStackTrace();
			}
			
		}
		
		return usageLinkList;
	}
	
	/**
	 * 获取excel中的表头
	 * @param sheet
	 * @return
	 * 
	 */
	private static Map<Integer, String> getHeader(Sheet sheet) {
		Map<Integer, String> headerMap = new HashMap<Integer, String>();
		
		Row row =  sheet.getRow(ImportConstants.BOM_HEADER_ROW_INDEX);
		
		if( row != null ){
			Iterator<Cell> iterator =   row.cellIterator();
			while ( iterator.hasNext() ) {
				Cell cell = iterator.next();
				
				String header = ImportedExcelUtil.getCellValueAsString(cell).trim();
				Integer columnIndex =  cell.getColumnIndex();
				if( !header.equals( "" ) ){
					headerMap.put(columnIndex, header);
				}				
			}			
		}
					
		return headerMap;
	}
	
	/**
	 * 根据视图,编号,版本(指定大版本)获取相应对象
	 * @param parentNumber
	 * @param parentView
	 * @param parentVersion
	 * @return
	 */
	private static WTPart getParentPart(String parentNumber, String parentView,String parentVersion) {
		WTPart parentPart = null;
		try {
			
			if( !parentVersion.equals("") ){
				parentPart = MyPartUtil.getWTPartByNumViewAndVersion(parentNumber, parentView, parentVersion);
				if( parentPart == null ){
					parentPart = CoreUtil.getWTPartByNumberAndView( parentNumber , parentView );
				}
				
			}else if( parentVersion.equals("") ){
				parentPart = CoreUtil.getWTPartByNumberAndView( parentNumber , parentView );			}
			
		} catch (WTException e) {
			e.printStackTrace();
		}
			
		return parentPart;
	}
	
	public static void main(String[] args) {
		
		if( args == null || args.length != 1 ){
			log.info( "Debug   参数列表..." );
			return;
		}
		
		if (!RemoteMethodServer.ServerFlag) {
			String method = "importSubstituteLink";			
		
				try {
					log.info( "Debug   RemoteMethodServer..." );
					RemoteMethodServer.getDefault().invoke(method, CLASSNAME, null,
							new Class[] { String.class }, new Object[] { args[0] });
					log.info( "Debug  end RemoteMethodServer..." );
				} catch (RemoteException e) {
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					e.printStackTrace();
				}
			
		}else{
			log.info( "Debug   importBoms..." );
		//	importSubstituteLink( args[0] ) ;
			log.info( "Debug   end importBoms..." );
		}
	}
	/**
	 * 取替换件关系
	 * @param substituteMaster
	 * @param wtcol
	 * @return
	 */
	public static WTPartSubstituteLink getSubstituteLink(WTPartMaster substituteMaster, WTCollection wtcol) {
		boolean hasSubstituteLink = false;
		
		log.info( "Debug   wtcol："+wtcol.size() );
		
		WTPartSubstituteLink wtSubstituteLink = null ;
		if( wtcol == null ){
			return wtSubstituteLink ; 
		}
		Iterator wtcolIterator = wtcol.iterator();
		while( wtcolIterator.hasNext() ){
			Object object = wtcolIterator.next() ;
			
			if( object != null && object instanceof ObjectReference ){
				ObjectReference orf = ( ObjectReference )object;
				Object obj = orf.getObject();
				
				if( obj != null && obj instanceof WTPartSubstituteLink ){
					wtSubstituteLink = ( WTPartSubstituteLink )obj;
				}
			}else if( object != null && object instanceof WTPartSubstituteLink ){
				wtSubstituteLink = ( WTPartSubstituteLink ) object ;
			}
			
			if( wtSubstituteLink != null ){
				WTPartMaster subMaster = wtSubstituteLink.getSubstitutes();
				log.info("=========getSubstituteLink number 1=========="+subMaster.getNumber());
				hasSubstituteLink = PersistenceHelper.isEquivalent(subMaster , substituteMaster ) ;
				if( hasSubstituteLink ){
					log.info("=========getSubstituteLink number 2=========="+subMaster.getNumber());
					return  wtSubstituteLink ;
				}
			}
		}
		
		return  null ;
	}
	
	/**
	 * 取替换件关系
	 * @param substituteMaster
	 * @param wtcol
	 * @return
	 * @throws WTException 
	 */
	public static Map<String,String> getSubstituteLinkList(WTPartUsageLink link) throws WTException {
		Map<String,String> list = new HashMap<String,String>();
		
		WTCollection wtcol = WTPartHelper.service.getSubstituteLinks(link) ;
		
		log.info( "Debug   wtcol："+wtcol.size() );
		
		WTPartSubstituteLink wtSubstituteLink = null ;
		if( wtcol == null || (wtcol !=null && wtcol.size()==0 )){
			return list ; 
		}
		Iterator wtcolIterator = wtcol.iterator();
		while( wtcolIterator.hasNext() ){
			Object object = wtcolIterator.next() ;
			
			if( object != null && object instanceof ObjectReference ){
				ObjectReference orf = ( ObjectReference )object;
				Object obj = orf.getObject();
				
				if( obj != null && obj instanceof WTPartSubstituteLink ){
					wtSubstituteLink = ( WTPartSubstituteLink )obj;
				}
			}else if( object != null && object instanceof WTPartSubstituteLink ){
				wtSubstituteLink = ( WTPartSubstituteLink ) object ;
			}
			
			if( wtSubstituteLink != null ){
				WTPartMaster subMaster = wtSubstituteLink.getSubstitutes();
				log.info("=========getSubstituteLink number 1=========="+subMaster.getNumber());
				if(subMaster != null && !list.containsKey(subMaster.getNumber())){
					String subamout = "";
					if(wtSubstituteLink.getQuantity().getAmount()!=null){
						subamout = Double.toString(wtSubstituteLink.getQuantity().getAmount());
					}
					wtSubstituteLink.getQuantity().getAmount();
					list.put(subMaster.getNumber(), StringUtil.isNullOrEmpty(subamout)?"":subamout);
				}
			}
		}
		log.info("=========getSubstituteLink number =========="+list.toString());
		return  list ;
	}
}
